#pragma once

#include <QWidget>
#include "Const.h"
#include "Man.h"

// 游戏
class Game: public QObject {
    Q_OBJECT

    // 移动结点
    class MoveNode {
        private: BaseGameObject* box;   // 被推动的箱子
        private: int direction;         // 移动方向

        /**
         * 构造方法。
         * @param box       被推动的箱子
         * @param direction 移动方向
         */
        public: MoveNode(BaseGameObject* box, int direction) :
            box(box),
            direction(direction) {
        }

        /**
         * 获取箱子。
         * @return 箱子
         */
        BaseGameObject* getBox() {
            return box;
        }

        /**
         * 获取方向。
         * @return 方向
         */
        int getDirection() {
            return direction;
        }
    };

    // 状态
    private: enum Status {
        END,    // 已结束
        PLAYING // 游戏中
    };

    signals: void UM_MAN_MOVED(int);    // 小人移动事件
    signals: void UM_GOTO_LEVEL(int);   // 进入关卡事件
    signals: void UM_GAME_OVER(bool);   // 游戏结束事件

    private: QPixmap* mBitmap;              // 后台缓冲位图
    private: int mBoxCount;                 // 未到达目的地的箱子数
    private: QPainter mDrawer;              // 绘图者
    private: QWidget* mGameBoard;           // 游戏区域
    private: int mLevel;                    // 关卡数
    private: Man* mMan;                     // 小人
    private: int mMoveCount;                // 移动次数
    private: QList<MoveNode*> mMoveList;    // 所有移动结点
    private: Status mStatus;                // 状态
    public: static BaseGameObject* sBaseGameObjects[Const::GAME_BOARD_GRID_COUNT_V][Const::GAME_BOARD_GRID_COUNT_H];    // 所有游戏物体

    public: Game(QPixmap*, QWidget*);
    public: ~Game();
    private: void clear();
    private: void enterLevel();
    private: void gameOver(bool);
    public: int getLevel();
    public: void gotoLevel(int);
    private: void gotoNextLevel();
    private: bool isWon();
    public: void onKeyPressed(int);
    public: void restart();
    public: void undo();
};
